/***************************************************************************
 *                                                                         *
 * Copyright (c) 2007 - 2009 Nuvoton Technology Corp. All rights reserved.*
 *                                                                         *
 ***************************************************************************/
 

#ifdef ECOS
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "drv_api.h"
#include "diag.h"
#include "wbio.h"
#include "NUC900_GE.h"
#include "NUC900_reg.h"
#else
#include <stdio.h>
#include "NUC900_GE.h"
#include "wbio.h"
#ifdef _NUC900_
#include "NUC900_reg.h"
#else
#include "reg702.h"
#endif
#endif

int _ImageWidth, _ImageHeight;

///////////////////////////////////////////////////////////////////////////////
//
// Function: load_image()
//
// Description:
//   Load image into creative buffer. 
//   The RGB888 source image must be converted to DDB. ?
//   This function transfers those forms
//   RGB888 to RGB565 or RGB332
//   RGB565 to RGB332 or RGB888
//   RGB332 to RGB565 or RGB888
///////////////////////////////////////////////////////////////////////////////
int load_image(int format, int width, int height, void *buf, void *file)
{
  FILE *image_file;
  UINT8 *ptr_RGB;
  UINT8 *ptr8, r8, g8, b8;
  UINT16 *ptr16, r16, g16, b16, g16_1, g16_2;
  UINT32 *ptr32, r32, g32, b32, g32_1, g32_2;
  int file_size, idx;
  void *tempbuffer;  // for transfering rgb data
  
  _ImageWidth = width;
  _ImageHeight = height;
/*
  image_file = fopen(filepath, "rb");  

#ifdef DEBUG   
  if(RGB332==format)
  	printf("load_image(RGB332): width=%d height=%d\n", _ImageWidth, _ImageHeight);
  else if(format==RGB565)
  	printf("load_image(RGB565): width=%d height=%d\n", _ImageWidth, _ImageHeight);
  else if(format==RGB888)
  	printf("load_image(RGB888): width=%d height=%d\n", _ImageWidth, _ImageHeight);
#endif 
 
  if (image_file==NULL)
  {
  #ifdef DEBUG 
    printf("load image fails\n");
  #endif
    return Fail;
  }
  else
  {
  	if(format == RGB888)
	    file_size = _ImageWidth * _ImageHeight * 4;
    else if(format == RGB565)
    	file_size = _ImageWidth * _ImageHeight * 2;
   	else if(format == RGB332)
   		file_size = _ImageWidth * _ImageHeight;
   	else
   		return Fail;
   	
   	tempbuffer = malloc(file_size);
    //fread(buf, 1, file_size, image_file);
    fread(tempbuffer, 1, file_size, image_file);
    //printf("tempbufer pp %x\n", (int)tempbuffer);
    fclose(image_file);
  }
*/
  	ptr_RGB = (UINT8 *)file;
	
	if(format == RGB888) 
	{	
		if (GFX_BPP==8)
		{
		  ptr8 = (UINT8 *)buf;
		  
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    b8 = (UINT8)(*ptr_RGB++) & 0xc0; // 2 bits
		    g8 = (UINT8)(*ptr_RGB++) & 0xe0; // 3 bits
		    r8 = (UINT8)(*ptr_RGB++) & 0xe0; // 3 bits
		    ptr_RGB++;
		    *ptr8++ = r8 | (g8>>3) | (b8>>6);
		  }
		} 
		else if (GFX_BPP==16)
		{
		  ptr16 = (UINT16 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    //printf("(UINT8)(*ptr_RGB++) is %x\n",(UINT8)(*ptr_RGB++));
		    b16 = (UINT8)(*ptr_RGB++) & 0x000f8; // 5 bits
		    g16 = (UINT8)(*ptr_RGB++) & 0x000fc; // 6 bits
		    r16 = (UINT8)(*ptr_RGB++) & 0x000f8; // 5 bits
		    ptr_RGB++;
		    *ptr16++ = (r16<<8) | (g16<<3) | (b16>>3);
		  }
		}
		else if (GFX_BPP==32)
		{
		  ptr32 = (UINT32 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    b32 = (UINT8)(*ptr_RGB++); 
		    g32 = (UINT8)(*ptr_RGB++);
		    r32 = (UINT8)(*ptr_RGB++);
		    ptr_RGB++;  //skip the zeros at MSB
		    *ptr32++ = 0<<24 | (r32<<16) | (g32<<8) | b32;
		  }
		}
	}
	else if(format == RGB565) 
	{
		if (GFX_BPP==8)
		{
		  ptr8 = (UINT8 *)buf;
		  
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    b8 = (UINT8)(*ptr_RGB++) & 0x00018; // 2 bits
      		g8 = (UINT8)(*ptr_RGB) & 0x00007;  // 3 bits
		    r8 = (UINT8)(*ptr_RGB++) & 0x000e0;  // 3bits
		    *ptr8++ = r8 | (g8<<2) | (b8>>3);
		  }
		} 
		else if (GFX_BPP==16)
		{
		  ptr16 = (UINT16 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    *ptr16++ = (*ptr_RGB) | (*(ptr_RGB+1)) << 8;
		    ptr_RGB+=2;
		  }
		}
		else if (GFX_BPP==32)
		{
		  ptr32 = (UINT32 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    //printf("(UINT8)(*ptr_RGB) is %x\n",(UINT8)(*ptr_RGB));
		    b32 = (UINT8)(*ptr_RGB) & 0x1f;      // 5 bits 
		    g32_1 = (UINT8)(*ptr_RGB++) & 0xe0;  // front 3 bits
		    g32_2 = (UINT8)(*ptr_RGB) & 0x07;    // back 3 bits
		    g32 = ((g32_1>>5) | (g32_2<<3))<<2;
		    r32 = (UINT8)(*ptr_RGB++) & 0xf8;    // 5 bits
		    *ptr32++ = 0<<24 | (r32<<16) | (g32<<8) | (b32<<3);
		    //printf("rgb is %x\n", 0<<24 | (r32<<16) | (g32<<8) | b32<<3);
		  }
		}
	}
	else if(format == RGB332)
	{
		if (GFX_BPP==8)
		{
		  ptr8 = (UINT8 *)buf;
		  
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    *ptr8++ = *ptr_RGB;
		    ptr_RGB++;
		  }
		} 
		else if (GFX_BPP==16)
		{
		  ptr16 = (UINT16 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    //printf("(UINT8)(*ptr_RGB) is %x\n",(UINT8)(*ptr_RGB));
		    r16 = (UINT8)(*ptr_RGB) & 0xe0; // 3 bits
		    g16_1 = (UINT8)(*ptr_RGB) & 0x10;
		    g16_2 = (UINT8)(*ptr_RGB) & 0x0c;
		    g16 = (g16_1>>2) | (g16_2>>2);
		    b16 = (UINT8)(*ptr_RGB++) & 0x3; // 2 bits
		    *ptr16++ = (r16<<8) | (g16<<8) | (b16<<3);
		    //printf("rgb is %x\n", (r16<<8) | (g16<<8) | (b16<<3));
		  }
		}
		else if (GFX_BPP==32)
		{
		  ptr32 = (UINT32 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    //printf("(UINT8)(*ptr_RGB) is %x\n",(UINT8)(*ptr_RGB));
		    r32 = (UINT8)(*ptr_RGB) & 0xe0;  // 3 bits 
		    g32 = (UINT8)(*ptr_RGB) & 0x1c;  // 3 bits
		    b32 = (UINT8)(*ptr_RGB++) & 0x3;  // 2 bits
		    *ptr32++ = 0<<24 | (r32<<15) | (g32<<11) | (b32<<6);
		    //printf("rgb is %x\n", 0<<24 | (r32<<16) | (g32<<8) | b32);
		  }
		}
	}
   
    return Successful;
    free(tempbuffer);
    #ifdef DEBUG 
  	printf("exit load_image()\n");
  	#endif
}
///////////////////////////////////////////////////////////////////////////////
//
// Function: load_image_from_file()
//
// Description:
//   Load image into creative buffer. 
//   The RGB888 source image must be converted to DDB. ?
//   This function transfers those forms
//   RGB888 to RGB565 or RGB332
//   RGB565 to RGB332 or RGB888
//   RGB332 to RGB565 or RGB888
///////////////////////////////////////////////////////////////////////////////
int load_image_from_file(int format, int width, int height, void *buf, char *filepath)
{
  FILE *image_file;
  UINT8 *ptr_RGB;
  UINT8 *ptr8, r8, g8, b8;
  UINT16 *ptr16, r16, g16, b16, g16_1, g16_2;
  UINT32 *ptr32, r32, g32, b32, g32_1, g32_2;
  int file_size, idx;
  void *tempbuffer;  // for transfering rgb data
  
  _ImageWidth = width;
  _ImageHeight = height;
  image_file = fopen(filepath, "rb");  

#ifdef DEBUG   
  if(RGB332==format)
  	printf("load_image(RGB332): width=%d height=%d\n", _ImageWidth, _ImageHeight);
  else if(format==RGB565)
  	printf("load_image(RGB565): width=%d height=%d\n", _ImageWidth, _ImageHeight);
  else if(format==RGB888)
  	printf("load_image(RGB888): width=%d height=%d\n", _ImageWidth, _ImageHeight);
#endif 
 
  if (image_file==NULL)
  {
  #ifdef DEBUG 
    printf("load image fails\n");
  #endif
    return Fail;
  }
  else
  {
  	if(format == RGB888)
	    file_size = _ImageWidth * _ImageHeight * 4;
    else if(format == RGB565)
    	file_size = _ImageWidth * _ImageHeight * 2;
   	else if(format == RGB332)
   		file_size = _ImageWidth * _ImageHeight;
   	else
   		return Fail;
   	
   	tempbuffer = (void *)malloc(file_size);
    //fread(buf, 1, file_size, image_file);
    fread(tempbuffer, 1, file_size, image_file);
    //printf("tempbufer pp %x\n", (int)tempbuffer);
    fclose(image_file);
  }

  	ptr_RGB = (UINT8 *)tempbuffer;
	
	if(format == RGB888) 
	{	
		if (GFX_BPP==8)
		{
		  ptr8 = (UINT8 *)buf;
		  
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    b8 = (UINT8)(*ptr_RGB++) & 0xc0; // 2 bits
		    g8 = (UINT8)(*ptr_RGB++) & 0xe0; // 3 bits
		    r8 = (UINT8)(*ptr_RGB++) & 0xe0; // 3 bits
		    ptr_RGB++;
		    *ptr8++ = r8 | (g8>>3) | (b8>>6);
		  }
		} 
		else if (GFX_BPP==16)
		{
		  ptr16 = (UINT16 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    //printf("(UINT8)(*ptr_RGB++) is %x\n",(UINT8)(*ptr_RGB++));
		    b16 = (UINT8)(*ptr_RGB++) & 0x000f8; // 5 bits
		    g16 = (UINT8)(*ptr_RGB++) & 0x000fc; // 6 bits
		    r16 = (UINT8)(*ptr_RGB++) & 0x000f8; // 5 bits
		    ptr_RGB++;
		    *ptr16++ = (r16<<8) | (g16<<3) | (b16>>3);
		  }
		}
		else if (GFX_BPP==32)
		{
		  ptr32 = (UINT32 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    b32 = (UINT8)(*ptr_RGB++); 
		    g32 = (UINT8)(*ptr_RGB++);
		    r32 = (UINT8)(*ptr_RGB++);
		    ptr_RGB++;  //skip the zeros at MSB
		    *ptr32++ = 0<<24 | (r32<<16) | (g32<<8) | b32;
		  }
		}
	}
	else if(format == RGB565) 
	{
		if (GFX_BPP==8)
		{
		  ptr8 = (UINT8 *)buf;
		  
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    b8 = (UINT8)(*ptr_RGB++) & 0x00018; // 2 bits
      		g8 = (UINT8)(*ptr_RGB) & 0x00007;  // 3 bits
		    r8 = (UINT8)(*ptr_RGB++) & 0x000e0;  // 3bits
		    *ptr8++ = r8 | (g8<<2) | (b8>>3);
		  }
		} 
		else if (GFX_BPP==16)
		{
		  ptr16 = (UINT16 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    *ptr16++ = (*ptr_RGB) | (*(ptr_RGB+1)) << 8;
		    ptr_RGB+=2;
		  }
		}
		else if (GFX_BPP==32)
		{
		  ptr32 = (UINT32 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    //printf("(UINT8)(*ptr_RGB) is %x\n",(UINT8)(*ptr_RGB));
		    b32 = (UINT8)(*ptr_RGB) & 0x1f;      // 5 bits 
		    g32_1 = (UINT8)(*ptr_RGB++) & 0xe0;  // front 3 bits
		    g32_2 = (UINT8)(*ptr_RGB) & 0x07;    // back 3 bits
		    g32 = ((g32_1>>5) | (g32_2<<3))<<2;
		    r32 = (UINT8)(*ptr_RGB++) & 0xf8;    // 5 bits
		    *ptr32++ = 0<<24 | (r32<<16) | (g32<<8) | (b32<<3);
		    //printf("rgb is %x\n", 0<<24 | (r32<<16) | (g32<<8) | b32<<3);
		  }
		}
	}
	else if(format == RGB332)
	{
		if (GFX_BPP==8)
		{
		  ptr8 = (UINT8 *)buf;
		  
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    *ptr8++ = *ptr_RGB;
		    ptr_RGB++;
		  }
		} 
		else if (GFX_BPP==16)
		{
		  ptr16 = (UINT16 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    //printf("(UINT8)(*ptr_RGB) is %x\n",(UINT8)(*ptr_RGB));
		    r16 = (UINT8)(*ptr_RGB) & 0xe0; // 3 bits
		    g16_1 = (UINT8)(*ptr_RGB) & 0x10;
		    g16_2 = (UINT8)(*ptr_RGB) & 0x0c;
		    g16 = (g16_1>>2) | (g16_2>>2);
		    b16 = (UINT8)(*ptr_RGB++) & 0x3; // 2 bits
		    *ptr16++ = (r16<<8) | (g16<<8) | (b16<<3);
		    //printf("rgb is %x\n", (r16<<8) | (g16<<8) | (b16<<3));
		  }
		}
		else if (GFX_BPP==32)
		{
		  ptr32 = (UINT32 *)buf;
		    
		  for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
		  {
		    //printf("(UINT8)(*ptr_RGB) is %x\n",(UINT8)(*ptr_RGB));
		    r32 = (UINT8)(*ptr_RGB) & 0xe0;  // 3 bits 
		    g32 = (UINT8)(*ptr_RGB) & 0x1c;  // 3 bits
		    b32 = (UINT8)(*ptr_RGB++) & 0x3;  // 2 bits
		    *ptr32++ = 0<<24 | (r32<<15) | (g32<<11) | (b32<<6);
		    //printf("rgb is %x\n", 0<<24 | (r32<<16) | (g32<<8) | b32);
		  }
		}
	}
   
    free(tempbuffer);
    #ifdef DEBUG 
  	printf("exit load_image()\n");
  	#endif
}

///////////////////////////////////////////////////////////////////////////////
//
// Function: load_image()
//
// Description:
//   Load image into offscreen buffer. 
//   The RGB888 source image must be converted to DDB. 
//   This function transfers RGB888 to RGB565 or RGB 332
///////////////////////////////////////////////////////////////////////////////
/*
void load_image(int id)
{
  FILE *image_file;
  UINT8 *ptr_RGB;
  UINT8 *ptr8, r8, g8, b8;
  UINT16 *ptr16, r16, g16, b16;
  int file_size, idx;
  
  if (id==0) 
  {
    _ImageWidth = 40;
    _ImageHeight = 30;
    //_ImageWidth = 160;
    //_ImageHeight = 120;
    image_file = fopen(IMAGE_40_FILE, "rb");
  }
  else if (id==1)
  {
    _ImageWidth = 160;
    _ImageHeight = 120;
    image_file = fopen(IMAGE_160_FILE, "rb");
  }
  else if (id==2)
  {
    _ImageWidth = 320;
    _ImageHeight = 240;
    image_file = fopen(IMAGE_320_FILE, "rb");
  }
  else if (id==3)
  {
    _ImageWidth = 320;
    _ImageHeight = 240;
    image_file = fopen(IMAGE_KEY_FILE, "rb");  
  }
  
  printf("load_image(%d): width=%d height=%d\n", id, _ImageWidth, _ImageHeight);
  
  if (image_file==NULL)
  {
    printf("load image fails\n");
  }
  else
  {
    file_size = _ImageWidth * _ImageHeight * 4;
    fread(_ColorSrcBufferPtr, 1, file_size, image_file);
    fclose(image_file);
  }
  
  ptr_RGB = (UINT8 *)_ColorSrcBufferPtr;

  if (GFX_BPP==8)
  {
    ptr8 = (UINT8 *)_ColorSrcBufferPtr;
    
    for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
    {
      b8 = (UINT8)(*ptr_RGB++) & 0xc0; // 2 bits
      g8 = (UINT8)(*ptr_RGB++) & 0xe0; // 3 bits
      r8 = (UINT8)(*ptr_RGB++) & 0xe0; // 3 bits
      ptr_RGB++;
      *ptr8++ = r8 | (g8>>3) | (b8>>6);
    }
  } 
  else if (GFX_BPP==16)
  {
    ptr16 = (UINT16 *)_ColorSrcBufferPtr;
    
    for (idx=0; idx<(_ImageWidth*_ImageHeight); idx++)
    {
      b16 = (UINT16)(*ptr_RGB++) & 0x000f8; // 5 bits
      g16 = (UINT16)(*ptr_RGB++) & 0x000fc; // 6 bits
      r16 = (UINT16)(*ptr_RGB++) & 0x000f8; // 5 bits
      ptr_RGB++;
      *ptr16++ = (r16<<8) | (g16<<3) | (b16>>3);
    }
  }
   
  printf("exit load_image()\n");
}
*/